package com.jswdwsx.esign.controller

import com.jswdwsx.esign.entity.OrgPO
import com.jswdwsx.esign.entity.UserPO
import com.jswdwsx.esign.extension.toDateTimeString
import com.jswdwsx.esign.protocol.Token
import com.jswdwsx.esign.protocol.request.AddComponentsReq
import com.jswdwsx.esign.protocol.request.OrgReq
import com.jswdwsx.esign.protocol.request.UpdateOrgReq
import com.jswdwsx.esign.protocol.request.UserReq
import com.jswdwsx.esign.protocol.response.*
import com.jswdwsx.esign.service.*
import com.jswdwsx.esign.util.base64Image
import com.jswdwsx.esign.util.md5File
import com.jswdwsx.esign.util.md5FileClassical
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile


@Api(tags = ["管理接口"])
@RestController
@RequestMapping("/v1/api/manager")
class ManagerController(
    private val fileTemplateService: FileTemplateService,
    private val accountService: AccountService,
    private val organizationService: OrganizationService,
    private val signService: SignService,
    private val flowService: FlowService,
    private val storedTokenService: StoredTokenService
) {

    private val logger = LoggerFactory.getLogger(NotifyController::class.java)

    @ApiOperation("查询文件模板信息")
    @GetMapping("/file-templates/{fileTemplateId}")
    fun queryTemplate(@PathVariable("fileTemplateId") fileTemplateId: String): QueryFileTemplateResp {
        logger.info("查询文件模板信息")
        return fileTemplateService.queryTemplate(fileTemplateId)
    }

    /**
     * @param templateName 会作为E签宝的模板名，最终加上后缀".pdf"会作为E签宝模板名
     */
    @ApiOperation("创建文件模板")
    @PostMapping("/{flowTemplateId}/file-templates")
    fun flow(
        @PathVariable("flowTemplateId") flowTemplateId: String,
        @RequestParam("templateName") templateName: String,
        @RequestParam("file") file: MultipartFile
    ): String {
        logger.info("开始上传文件创建模板")
        fileTemplateService.createFileTemplate(flowTemplateId, templateName, file)
        return "success"
    }

    @ApiOperation("添加文本域到文件模板")
    @PostMapping("/file-templates/{templateId}/add-component")
    fun addComponent(@PathVariable("templateId") templateId: String, @RequestBody addComponentsReq: AddComponentsReq): Boolean {
        logger.info("开始为模板添加文本域")
        return fileTemplateService.addComponent(templateId, addComponentsReq)
    }

    @ApiOperation("设置静默签署")
    @PostMapping("/accounts/{accountId}/silent")
    fun setSilentSign(@PathVariable("accountId") accountId: String): Boolean {
        logger.info("开始设置静默签署")
        return accountService.setSilentSign(accountId)
    }

    @ApiOperation("创建User")
    @PostMapping("/accounts/")
    fun createAccount(@RequestBody userReq: UserReq): UserPO {
        logger.info("开始创建User")
        return accountService.createAccount(userReq)
    }

    @ApiOperation("查询User信息")
    @GetMapping("/accounts/{accountId}")
    fun queryAccount(@PathVariable("accountId") accountId: String): UpdateUserResp {
        logger.info("开始查询User信息")
        return accountService.queryAccount(accountId)
    }

    @ApiOperation("创建Org")
    @PostMapping("/orgs/")
    fun createOrg(@RequestBody orgReq: OrgReq): OrgPO {
        logger.info("开始创建Org")
        return organizationService.createOrg(orgReq)
    }

    @ApiOperation("查询Org")
    @PostMapping("/orgs/{orgId}")
    fun queryOrg(@PathVariable orgId: String): QueryOrgResp {
        logger.info("开始创建Org")
        return organizationService.queryOrg(orgId)
    }

    @ApiOperation("更新Org")
    @PutMapping("/orgs/{orgId}")
    fun updateOrg(@PathVariable orgId: String, @RequestBody updateOrgReq: UpdateOrgReq): OrgPO? {
        logger.info("开始更新Org")
        return organizationService.updateOrganization(orgId, updateOrgReq)
    }

    @ApiOperation("查询企业印章")
    @PostMapping("/{orgId}/seals")
    fun queryOrgSeals(@PathVariable orgId: String): QueryOrgSealResp? {
        logger.info("开始创建Org")
        return organizationService.queryOrgSeals(orgId)
    }

    @ApiOperation("查询签署流程")
    @GetMapping("/flows/{flowId}")
    fun queryFlowStatus(@PathVariable("flowId") flowId: String): QueryFlowResp {
        logger.info("开始查询签署流程")
        return flowService.queryFlow(flowId)
    }

    @ApiOperation("查询签署流程的签署区列表")
    @GetMapping("/flows/{flowId}/signfields")
    fun queryFlowSignFields(@PathVariable("flowId") flowId: String): QueryFlowSignFieldsResp {
        logger.info("开始查询签署流程")
        return flowService.queryFlowSignFields(flowId)
    }

    @ApiOperation("获取流程文件下载地址")
    @GetMapping("/flows/{flowId}/docs")
    fun getDocsDownloadUrl(@PathVariable("flowId") flowId: String): DocsDownloadUrlResp? {
        logger.info("开始获取流程文件下载地址")
        return flowService.getDocsDownloadUrl(flowId)
    }

    @ApiOperation("测试获取文件MD5值")
    @PostMapping("/test/md5-file")
    fun md5Test(@RequestParam("file") file: MultipartFile): String {
        logger.info("开始md5test")
        return "测试结果${Pair(md5File(file), md5FileClassical(file))}"
    }

    @ApiOperation("测试Base64编码图片")
    @PostMapping("/test/base64-file")
    fun createSealImage(
        @RequestParam("file") file: MultipartFile
    ): String? {
        logger.info("创建图片印章")
        return base64Image(file)
    }

    @ApiOperation("下载签署文件")
    @PostMapping("/{flowId}/download")
    fun downloadTest(@PathVariable("flowId") flowId: String): List<Doc>? {
        logger.info("开始下载签署文件")
        return flowService.downloadFlowFile(flowId)
    }

    @ApiOperation("创建图片印章")
    @PostMapping("/{accountId}/seals/image")
    fun createSealImage(
        @PathVariable("accountId") accountId: String, @RequestParam("file") file: MultipartFile
    ): SealImageResp {
        logger.info("创建图片印章")
        return accountService.createSealImage(accountId, file)
    }

    @ApiOperation("获取支付宝小程序签署链接")
    @GetMapping("alipay-sign-url")
    fun getAlipaySignUrl(flowId: String, signerId: String): String {
        logger.info("获取支付宝小程序签署链接:${storedTokenService.storedToken}")
        return signService.getAlipaySignUrl(flowId, signerId)
    }

    @ApiOperation("查看token接口")
    @GetMapping("token")
    fun catToken(): MutableMap<String, Token> {
        logger.info("查看token:${storedTokenService.storedToken}")
        val catToken = storedTokenService.catToken()
        catToken.values.forEach {
            logger.info("token的失效时间是${it.expiresIn}：${it.expiresIn.toDateTimeString()}")
        }
        return catToken
    }
}
